/*******************************************************
> Copyright (C) 2024 ==iot== All rights reserved.
> File Name: client.c
> Author: wyf
> Created Time: 2024年08月15日 星期四 11时13分08秒
***************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h> // 目录名获取配合DIR
#include <assert.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h> // 文件控制操作
#include <sys/types.h> // 获取pid等
#include <sys/wait.h> // 等待子进程结束
#include <time.h> // 时间获取
#include <sys/ipc.h> // 进程通信
#include <sys/msg.h> // 消息队列
#include <sys/shm.h> // 共享内存
#include <signal.h> // 信号处理
#include <pthread.h> // 线程
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "cJSON.h"

struct msg {
    char operator[10];
    int number1;
    int number2;
    int result;
};

int main(int argc, const char* argv[]) {
    int sock = 0;
    int ret = 0;
    char buf[1024] = { 0 };

    struct sockaddr_in serAddr;
    memset(&serAddr, 0, sizeof(serAddr));
    serAddr.sin_family = AF_INET;
    serAddr.sin_port = htons(6981); // 设置服务器端口
    serAddr.sin_addr.s_addr = inet_addr("192.168.48.128"); // 设置服务器IP

    sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock == -1) {
        perror("sock");
        exit(-1);
    }

    ret = connect(sock, (struct sockaddr*)&serAddr, sizeof(serAddr));
    if (ret == -1) {
        perror("connect");
        exit(-1);
    }

    while (1) {
        // 赋值
        struct msg stb;
        int temp = 0;
        printf("请输入运算符：(加1，减2，乘3，除4)\n");
        scanf("%d", &temp);

        if (temp == 1)
            strcpy(stb.operator, "add");
        else if (temp == 2)
            strcpy(stb.operator, "sub");
        else if (temp == 3)
            strcpy(stb.operator, "mul");
        else if (temp == 4)
            strcpy(stb.operator, "div");
        else {
            printf("输入有误！\n");
            return 0;
        }

        printf("请输入第一个数：\n");
        scanf("%d", &stb.number1);
        printf("请输入第二个数：\n");
        scanf("%d", &stb.number2);

        // JSON格式化
        cJSON* json = cJSON_CreateObject();
        cJSON_AddStringToObject(json, "operator", stb.operator);
        cJSON_AddNumberToObject(json, "number1", stb.number1);
        cJSON_AddNumberToObject(json, "number2", stb.number2);
        char* dest = cJSON_Print(json);

        // 发送
        ret = send(sock, dest, strlen(dest), 0);
        if (ret == -1) {
            perror("send");
            exit(-1);
        }

        // 接收
        ret = recv(sock, buf, sizeof(buf), 0);
        if (ret == -1) {
            perror("recv");
            exit(-1);
        }
        else if (ret == 0) {
            printf("服务器断开连接。\n");
            close(sock);
            break;
        }

        // 字符串解析成JSON
        cJSON* json2 = cJSON_Parse(buf);
        if (json2 == NULL) {
            printf("客户端解析失败！\n");
            return 0;
        }

        // 检查是否为超时消息
        cJSON* type = cJSON_GetObjectItem(json2, "type");
        if (type != NULL && strcmp(type->valuestring, "timeout") == 0) {
            printf("收到服务器超时通知，客户端即将退出...\n");
            cJSON_Delete(json2);
            close(sock);
            exit(0);
        }

        // 获取计算结果
        int result = cJSON_GetObjectItem(json2, "result")->valueint;
        printf("result = %d\n", result);
        cJSON_Delete(json2);
    }

    // 关闭
    close(sock);
    return 0;
}
